"""
作者：黄瀚扬
时间：2023/11/6

"""
import turtle
import random
import time
# 全局变量定义
start_time =0
food=[]
at_food=0
score=0
snake_speed=20  # 蛇速度初始值
monster_speed=20  #
z=0
segments = []
last_direction="stop"


def start_timer():  # 计时函数
    current_time = int(time.time() - start_time)
    timer_turtle.clear()
    timer_turtle.write(f"{current_time}", align="center", font=("Arial", 20, "bold"))
    time.sleep(0.1)


def clear_text_and_continue(x, y):  # 清除文本并开始计时
    print("游戏开始啦")
    global start_time
    text_start.clear()
    create_food()
    start_time= time.time()


def go_up():  # 修改蛇头方向 向上
    if head.direction != "down":
        head.direction = "up"


def go_down():  # 修改蛇头方向 向下
    if head.direction != "up":
        head.direction = "down"


def go_left():  # 修改蛇头方向 向左
    if head.direction != "right":
        head.direction = "left"


def go_right():  # 修改蛇头方向 向右
    if head.direction != "left":
        head.direction = "right"


def pause():  # 修改蛇头方向 向右
    global last_direction
    if head.direction != "stop":
        last_direction = head.direction
        head.direction = "stop"
    else:
        head.direction = last_direction


def move():  # 蛇头移动函数
    # print("SNAKE_speed:", snake_speed)  # 输出蛇速度
    if head.direction == "stop":
        motion_turtle.clear()
        motion_turtle.write("Pause", align="center", font=("Arial", 20, "bold"))
        pass
    if head.direction == "up":
        head.sety(head.ycor() + snake_speed)
        motion_turtle.clear()
        motion_turtle.write("Up", align="center", font=("Arial", 20, "bold"))
    if head.direction == "down":
        head.sety(head.ycor() - snake_speed)
        motion_turtle.clear()
        motion_turtle.write("Down", align="center", font=("Arial", 20, "bold"))
    if head.direction == "left":
        head.setx(head.xcor() - snake_speed)
        motion_turtle.clear()
        motion_turtle.write("Left", align="center", font=("Arial", 20, "bold"))
    if head.direction == "right":
        head.setx(head.xcor() + snake_speed)
        motion_turtle.clear()
        motion_turtle.write("Right", align="center", font=("Arial", 20, "bold"))


class Food(turtle.Turtle):  # 食物类（继承turtle类）
    def __init__(self, number):
        super().__init__()
        self.number = number
        self.penup()
        self.x= random.randint(-230, 230)
        self.y= random.randint(-280, 190)
        self.speed(0)  # 设置绘制边界的速度为最快
        self.goto(self.x, self.y)
        self.write(number, align="center", font=("Arial", 10, "bold"))
        self.hideturtle()
        food.append((self.x, self.y))


def create_food():  # 创建食物并记录位置（1-9）
    global foods
    foods = [Food(i) for i in range(1, 10)]
    print(food)


def eat_food():  # 判断是否吃到食物并添加到变量
    global score, at_food, snake_speed
    for i in range(0, 9):
        if head.distance(food[i]) <22:
            at_food=i+1
            food[i]=(1000, 1000)
            print("Eat:", at_food)
            break
    if at_food !=0:
        score += at_food
        foods[at_food-1].clear()
        # 将蛇的长度增加
        for _ in range(at_food+1):
            new_segment = turtle.Turtle()
            new_segment.penup()
            segments.append(new_segment)
        update_score(score)
        snake_speed = 20 / (score*0.003+1)  # 修改蛇的速度
        at_food=0


def update_score(new_score):  # 更新得分
    contact_turtle.clear()
    contact_turtle.write(new_score, align="center", font=("Arial", 20, "bold"))
    pass


def move_monster():  # 怪物移动
    global z
    x=monster.xcor()
    y=monster.ycor()
    i = 1 if head.xcor() > x else -1 if head.xcor() < x else 0
    j = 1 if head.ycor() > y else -1 if head.ycor() < y else 0
    if z % 2 == 0:
        monster.setx(x + monster_speed * i)
    else:
        monster.sety(y + monster_speed * j)
    z+=1
    pass


def check_collision():  # 判断是否碰撞（游戏结束）
    if head.distance(monster) < 22 or not(-245<head.xcor()<245) or not(-285<head.ycor()<205):
        return True
    return False


def game_over():  # 游戏结束（失败）
    head.write("Game Over!", align="center", font=("Arial", 10, "bold"))
    # while 1:
    #     pass
    time.sleep(10)


def winner():  # 游戏结束（胜利）
    head.write("Winner!!!", align="center", font=("Arial", 10, "bold"))
    # while 1:
    #     pass
    time.sleep(10)


if __name__=='__main__':  # 主函数
    print("Welcome to HHY's version of snake ....")
    # 界面初始化
    win = turtle.Screen()
    win.title("Snake by hhy")
    win.bgcolor("white")
    win.setup(width=660, height=740)
    win.tracer(0)  # 关闭屏幕更新以优化游戏速度
    border = turtle.Turtle()
    border.penup()  # 抬起画笔，以便在移动到起始绘制点时不留下痕迹
    border.goto(-250, -290)  # 边界线左下角的起始点
    border.pendown()  # 放下画笔准备绘制
    border.speed(0)  # 设置绘制边界的速度为最快
    border.pensize(3)
    # 绘制正方形边界
    for _ in range(4):
        border.forward(500)  # 向前移动 500 像素
        border.left(90)  # 向左转 90 度
    border.goto(-250, 210)  # 边界线左下角的起始点
    for _ in range(2):
        border.forward(500)  # 向前移动 500 像素
        border.left(90)  # 向左转 90 度
        border.forward(80)  # 向前移动 500 像素
        border.left(90)  # 向左转 90 度
    border.hideturtle()
    text_turtle = turtle.Turtle()
    text_turtle.hideturtle()  # 隐藏写文本的 turtle
    text_turtle.penup()  # 抬起画笔
    text_turtle.goto(-25, 238)  # 移动到屏幕中心
    a = "Contact:     Time:      Motion:     "
    text_turtle.write(a, align="center", font=("Arial", 20, "bold"))  # 在屏幕中写文本
    text_start = turtle.Turtle()
    text_start.hideturtle()  # 隐藏开始文本
    text_start.penup()  # 抬起画笔
    text_start.goto(-225, 50)  # 移动到屏幕中心
    text_start.write("Welcome to HHY's version of snake ....\n"
                     "\n"
                     "You are going to use the 4 arrow keys to move the snake\n"
                     "around the screen,trying to consume all the food items\n"
                     "before the monster catches you ....\n"
                     "\n"
                     "Click anywhere on the screen to start the game,have fun!!", align="left",
                     font=("Arial", 13, "normal"))  # 开始文本
    # 初始化计时器显示的 turtle
    timer_turtle = turtle.Turtle()
    timer_turtle.hideturtle()  # 隐藏 timer_turtle
    timer_turtle.penup()  # 抬起画笔
    timer_turtle.goto(15, 238)  # 将 timer_turtle 移到屏幕上方
    timer_turtle.write("0", align="center", font=("Arial", 20, "bold"))
    # motion移动的 turtle
    motion_turtle = turtle.Turtle()
    motion_turtle.hideturtle()  # 隐藏 motion_turtle
    motion_turtle.penup()  # 抬起画笔
    motion_turtle.goto(190, 238)  # 将 timer_turtle 移到屏幕上方
    motion_turtle.write("Paused", align="center", font=("Arial", 20, "bold"))
    # contact分数的 turtle
    contact_turtle = turtle.Turtle()
    contact_turtle.hideturtle()
    contact_turtle.penup()  # 抬起画笔
    contact_turtle.goto(-100, 238)  # 将 contact_turtle 移到屏幕上方
    contact_turtle.write("0", align="center", font=("Arial", 20, "bold"))
    # head蛇头的 turtle
    head = turtle.Turtle()
    head.speed(0)
    head.shape("square")
    head.color("red")
    head.penup()
    head.goto(0, 0)
    head.direction = "stop"
    # Monster怪物的 turtle
    monster = turtle.Turtle()
    monster.speed(0)
    monster.shape("square")
    monster.color("purple")
    monster.penup()
    monster.goto(-100, -200)
    # 键盘触发事件
    win.listen()
    win.onkeypress(go_up, "Up")
    win.onkeypress(go_down, "Down")
    win.onkeypress(go_left, "Left")
    win.onkeypress(go_right, "Right")
    win.onkeypress(pause, "space")

    # 主循环
    while True:
        win.onclick(clear_text_and_continue)  # 鼠标点击后开始
        win.update()
        if start_time ==0:
            continue
        start_timer()
        move()
        move_monster()
        eat_food()
        # 是否被怪物追上
        if check_collision():
            game_over()
        if score>=45 and len(segments) >= 45:
            winner()
        # 首先以相反的顺序移动结束段
        for index in range(len(segments)-1, 0, -1):
            segments[index].speed(0)
            segments[index].shape("square")
            segments[index].pencolor("blue")
            segments[index].pensize(2)
            x = segments[index - 1].xcor()
            y = segments[index - 1].ycor()
            segments[index].goto(x, y)
        # 向上一段（蛇部分）移动
        if len(segments) > 0:
            x = head.xcor()
            y = head.ycor()
            segments[0].goto(x, y)
        time.sleep(0.2)

print("End Game ")
